﻿using System.Linq.Expressions;
using Infrastructure.Model.DI;
using Microsoft.Extensions.Logging;
using Model.CommonModel.PageModel;
using Model.EntityModel.Auth;
using Model.EntityModel.SysModel;
using Model.QueryModel.system;
using Repository.IRepository.ISysRepository;
using Repository.Repository.SysRepository;
using Service.IService.ISysService;
using SqlSugar;

namespace Service.Service.SysService
{
    [AppService(ServiceType = typeof(IUserService), ServiceLifetime = LifeTime.Scoped)]
    public class UserService : IUserService
    {
        private readonly IUserRepository _userRepo;
        private readonly IUserGroupRepository _userGroupRepo;
        private readonly IGroupRepository _groupRepo;
        private readonly ILogger<UserService> _logger;

        public UserService(
            IUserRepository userRepo,
            IUserGroupRepository userGroupRepo,
            IGroupRepository groupRepo,
            ILogger<UserService> logger)
        {
            _userRepo = userRepo;
            _userGroupRepo = userGroupRepo;
            _groupRepo = groupRepo;
            _logger = logger;
        }

        public User GetUserById(string userId)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                return _userRepo.GetUserById(userId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户信息失败，用户ID: {userId}");
                throw;
            }
        }

        public User GetUserByUsername(string username)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(username))
                    throw new ArgumentException("用户名不能为空", nameof(username));

                return _userRepo.GetUserByUsername(username);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户信息失败，用户名: {username}");
                throw;
            }
        }

        public bool CreateUser(User user)
        {
            try
            {
                if (user == null)
                    throw new ArgumentNullException(nameof(user), "用户信息不能为空");

                // 检查用户名是否已存在
                var existingUser = _userRepo.GetUserByUsername(user.UserName);
                if (existingUser != null)
                    throw new InvalidOperationException("用户名已存在");

                return _userRepo.CreateUser(user);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建用户失败，用户名: {user.UserName}");
                throw;
            }
        }

        public bool UpdateUser(User user)
        {
            try
            {
                if (user == null)
                    throw new ArgumentNullException(nameof(user), "用户信息不能为空");

                if (!_userRepo.UserExists(user.UserId))
                    throw new InvalidOperationException("用户不存在");

                return _userRepo.UpdateUser(user);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户失败，用户ID: {user.UserId}");
                throw;
            }
        }

        public bool UpdateUserStatus(string userId, string status)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                if (status != "A" && status != "I")
                    throw new ArgumentException("状态值必须是A(激活)或I(失效)", nameof(status));

                return _userRepo.UpdateUserStatus(userId, status);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户状态失败，用户ID: {userId}");
                throw;
            }
        }

        public bool UpdatePassword(string userId, string newPassword)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                if (string.IsNullOrWhiteSpace(newPassword))
                    throw new ArgumentException("新密码不能为空", nameof(newPassword));

                return _userRepo.UpdatePassword(userId, newPassword);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户密码失败，用户ID: {userId}");
                throw;
            }
        }

        public List<User> GetUsersByDepartment(string deptCode)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(deptCode))
                    throw new ArgumentException("部门编码不能为空", nameof(deptCode));

                return _userRepo.GetUsersByDepartment(deptCode);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门用户失败，部门编码: {deptCode}");
                throw;
            }
        }

        public bool AddGroupsToUser(string userId, List<string> groupIds)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                if (groupIds == null || !groupIds.Any())
                    throw new ArgumentException("至少需要选择一个组别", nameof(groupIds));

                // 验证用户存在性
                if (!_userRepo.UserExists(userId))
                    throw new InvalidOperationException("指定的用户不存在");

                // 验证组别有效性
                var validGroups = _groupRepo.GetActiveGroups();
                var invalidGroups = groupIds.Except(validGroups.Select(g => g.Id)).ToList();
                if (invalidGroups.Any())
                    throw new InvalidOperationException($"包含无效的组别ID: {string.Join(",", invalidGroups)}");

                // 添加关联
                return _userGroupRepo.AddGroupsToUser(userId, groupIds);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加组别到用户失败，用户ID: {userId}");
                throw;
            }
        }

        public bool RemoveGroupsFromUser(string userId, List<string> groupIds)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                if (groupIds == null || !groupIds.Any())
                    throw new ArgumentException("至少需要选择一个组别", nameof(groupIds));

                return _userGroupRepo.RemoveGroupsFromUser(userId, groupIds);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"从用户移除组别失败，用户ID: {userId}");
                throw;
            }
        }

        public List<Group> GetUserGroups(string userId)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                var relations = _userGroupRepo.GetUserGroups(userId);
                var groupIds = relations.Select(r => r.GroupId).ToList();

                if (!groupIds.Any())
                    return new List<Group>();

                return _groupRepo.GetGroupsByIds(groupIds);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户组别失败，用户ID: {userId}");
                throw;
            }
        }

        public List<Group> GetAvailableGroupsForUser(string userId)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(userId))
                    throw new ArgumentException("用户ID不能为空", nameof(userId));

                var allGroups = _groupRepo.GetActiveGroups();
                var userGroups = _userGroupRepo.GetUserGroups(userId);

                var userGroupIds = userGroups.Select(ug => ug.GroupId).ToList();
                return allGroups.Where(g => !userGroupIds.Contains(g.Id)).ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户可用组别失败，用户ID: {userId}");
                throw;
            }
        }

        public async Task<PagedInfo<User>> GetPagedUsersAsync(
            Expression<Func<User, bool>> whereExpression,
            int pageIndex = 1,
            int pageSize = 20,
            Expression<Func<User, object>> orderByExpression = null,
            OrderByType orderByType = OrderByType.Asc)
        {
            return await _userRepo.GetPagedListAsync(
                whereExpression,
                pageIndex,
                pageSize,
                orderByExpression,
                orderByType);
        }

        public PagedInfo<User> GetUserPage(int pageNum, int pageSize, QueryUser search)
        {
            try
            {
                var result = _userRepo.GetSearch(pageNum, pageSize, search);
                return result ?? throw new Exception("查询失败！");
            }
            catch (Exception ex)
            {
                throw new Exception("查询失败: " + ex.Message);
            }
        }
    }
}